<template>
	<view class='w-full h-full flex-center' :id="'container' + id" @tap="tap">
		<skeleton v-if="options === 'loading'" :style="{height: height + 'px',width: width + 'px'}"></skeleton>
		<empty-error v-else-if="!options || !options.series || options.series.length === 0" message='暂无数据' :width="width" :height="height"></empty-error>
		<canvas v-show="options && options.series && options.series.length > 0" :canvasId="id" :id="id" type="2d" :style="{width: width + 'px',height: height + 'px'}" 
			@touchstart="touchstart"
			@touchmove="touchmove"
			@touchend="touchend"/>
	</view>
</template>

<script>
	import { buildShortUUID } from "@/sl-uni-sdk/utils/uuid.js";
	import { isObj,deepMergeObj } from "@/sl-uni-sdk/utils/common.js";
	import { ref,getCurrentInstance,onMounted,nextTick,watch } from "vue";
	import uCharts from './u-charts.js';
	import EmptyError from "./empty-error.vue";
	import Skeleton from "@/sl-uni-sdk/components/common/skeleton/skeleton.vue";
	// #ifdef H5
	import initTouch from "./init-touch-h5.js";
	// #endif
	// #ifdef MP-WEIXIN
	import initTouch from "./init-touch-wx.js";
	// #endif
	import formatter from "./formatter.js";
	import ringOptions from "./options/ring.js";
	const DefaultOptions = {
		ring: ringOptions
	};
	function mergeOptions(type,newOptions){
		let defaultOptions = DefaultOptions[type];
		if(defaultOptions){
			defaultOptions = defaultOptions();
		}else{
			console.warn(`${type}'s default options is not define`);
			defaultOptions = {};
		}
		deepMergeObj(defaultOptions,newOptions);
		return defaultOptions;
	}
	export default {
		components: {
			EmptyError,
			Skeleton
		},
		props:{
			options: [Object,String],
			inScrollView: Boolean,
			pageScrollTop: {default: 0,type: Number},
			tooltipShow: {default: true,type: Boolean},
			tapLegend: {default: true,type: Boolean},
			tooltipFormat: String,
			type: {required: true,type: String},
			ontap: {default: true,type: Boolean}
		},
		name:"uchart-canvas",
		setup(props,setupCtx){
			const { ctx: vueCtx } = getCurrentInstance();
			const id = buildShortUUID("ucc");
			const containerId = 'container' + id;
			const width = ref(200);
			const height = ref(150);
			const common = {
				id,
				containerId,
				uChartsInstance: null,
				uOptions: null,
				vueCtx,
				tooltipDefault(item, category, index, opts) {
				  if (category) {
				    let data = item.data
				    if(typeof item.data === "object"){
				      data = item.data.value
				    }
				    return category + ' ' + item.name + ':' + data;
				  } else {
				    if (item.properties && item.properties.name) {
				      return item.properties.name;
				    } else {
				      return item.name + ':' + item.data;
				    }
				  }
				},
				showTooltip(e){
					let tc = common.uOptions.tooltipCustom;
					const tooltipFormatter = formatter.tooltip[props.tooltipFormat] || common.tooltipDefault;
					if (tc && tc !== undefined && tc !== null) {
					  let offset = undefined;
					  if (tc.x >= 0 && tc.y >= 0) {
					    offset = { x: tc.x, y: tc.y + 10 };
					  }
					  common.uChartsInstance.showToolTip(e, {
					    index: tc.index,
					    offset: offset,
					    textList: tc.textList,
							formatter: tooltipFormatter
					  });
					} else {
					  common.uChartsInstance.showToolTip(e, {
							formatter: tooltipFormatter
					  });
					}
				}
			};
			onMounted(() => {
				uni.createSelectorQuery().in(vueCtx).select('#' + containerId).boundingClientRect(data => {
					width.value = data.width;
					height.value = data.height;
					// #ifdef H5
					const ctx = uni.createCanvasContext(id, vueCtx);
					const propsOpts = typeof props.options == 'object' ? props.options : null;
					const options = mergeOptions(props.type,propsOpts || {});
					Object.assign(options,{
						width: data.width,
						height: data.height,
						pixelRatio: 1,
						context: ctx
					});
					common.uOptions = options;
					if(propsOpts){
						common.uChartsInstance = new uCharts(common.uOptions);
					}
					// #endif
					// #ifdef MP-WEIXIN
					uni.createSelectorQuery().in(vueCtx).select('#' + id).fields({ node: true, size: true }).exec((res) => {
						if (res[0]) {
							const pixelRatio = uni.getSystemInfoSync().pixelRatio;
							const canvas = res[0].node;
							const ctx = canvas.getContext('2d');
							canvas.width = width.value * pixelRatio;
							canvas.height = height.value * pixelRatio;
							const propsOpts = typeof props.options == 'object' ? props.options : null;
							const options = mergeOptions(props.type,propsOpts || {});
							Object.assign(options,{
								width: canvas.width,
								height: canvas.height,
								pixelRatio,
								canvas2d: true,
								context: ctx
							});
							common.uOptions = options;
							if(propsOpts){
								common.uChartsInstance = new uCharts(common.uOptions);
							}
						}
					});
					// #endif
				}).exec();
			});
			watch(() => props.options,(newOptions) => {
				if(typeof newOptions == 'string') return;
				deepMergeObj(common.uOptions,newOptions);
				if(common.uChartsInstance){
					common.uChartsInstance.updateData(common.uOptions);
				}else{
					common.uChartsInstance = new uCharts(common.uOptions);
				}
			});
			const touchResult = initTouch(props,setupCtx,common);
			return {
				id,
				width,
				height,
				...touchResult
			};
		}
	}
</script>

<style>

</style>
